package org.streets.eis.component;

import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.util.string.AppendingStringBuffer;

/**
 * use Wicket's AjaxFormComponentUpdatingBehavior cannot override getEventHandler,
 * 
 * so use this
 */
public abstract class AjaxFormComponentUpdatedBehavior extends AjaxEventBehavior{
	private static final long serialVersionUID = 1L;

	public AjaxFormComponentUpdatedBehavior(final String event){
		super(event);
	}

	@Override
	protected void onBind(){
		super.onBind();

		if (!(getComponent() instanceof FormComponent)){
			throw new RuntimeException("Behavior " + getClass().getName() +
				" can only be added to an instance of a FormComponent");
		}
	}

	protected final FormComponent<?> getFormComponent(){
		return (FormComponent<?>)getComponent();
	}

	@Override
	protected CharSequence getEventHandler(){
		return generateCallbackScript(new AppendingStringBuffer("wicketAjaxPost('").append(
			getCallbackUrl(false)).append(
			"', ").append(getPostData()));
	}

	@Override
	protected void onCheckEvent(String event){
		if ("href".equalsIgnoreCase(event)){
			throw new IllegalArgumentException(
				"this behavior cannot be attached to an 'href' event");
		}
	}

	@Override
	protected final void onEvent(final AjaxRequestTarget target){
		final FormComponent<?> formComponent = getFormComponent();

		if (getEvent().toLowerCase().equals("onblur") && disableFocusOnBlur()){
			target.focusComponent(null);
		}

		try{
			formComponent.inputChanged();
			formComponent.validate();
			if (formComponent.hasErrorMessage()){
				formComponent.invalid();
				onError(target, null);
			} else {
				formComponent.valid();
				if (getUpdateModel()){
					formComponent.updateModel();
				}

				onUpdate(target);
			}
		} catch (RuntimeException e)	{
			onError(target, e);
		}
	}

	protected boolean getUpdateModel(){
		return true;
	}

	protected boolean disableFocusOnBlur() {
		return true;
	}

	protected CharSequence getPostData(){
		return "wicketSerialize(Wicket.$('" + getComponent().getMarkupId() + "'))";
	}
	protected abstract void onUpdate(AjaxRequestTarget target);

	protected void onError(AjaxRequestTarget target, RuntimeException e)	{
		if (e != null){
			throw e;
		}
	}
}
